<?php

namespace app\admin\controller\system;

use app\admin\model\system\SystemGenTableColumn;
use app\admin\service\curd\BuildCurdService;
use app\admin\service\curd\GenService;
use app\common\controller\AdminController;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnotation;
use app\common\tools\PathTools;
use think\App;
use think\console\Input;
use think\console\Output;
use think\facade\Env;

/**
 * @ControllerAnnotation(title="Gen")
 */
class Gen extends AdminController
{

    use \app\admin\traits\Curd;

    public function __construct(App $app)
    {
        parent::__construct($app);

        $this->model = new \app\admin\model\system\SystemGenTable();

    }


    /**
     * @NodeAnotation(title="导入")
     */
    public function import()
    {
        if ($this->request->isAjax()) {
            if (input('selectFields')) {
                return $this->selectList();
            }
            list($page, $limit, $where, $excludes, $request_options, $group) = $this->buildTableParames();
            $sort = $this->request->param('sort') ?? '';
            list($count, $list) = $this->model::SelectDbTableList($page, $limit, $where, $sort);
            $data = [
                'code'  => 0,
                'msg'   => '',
                'count' => $count,
                'data'  => $list,
            ];
            return json($data);
        }
        return $this->fetch();
    }

    /**
     * @NodeAnotation(title="导入保存")
     */
    public function importSave()
    {
        $table_name = $this->request->param('table_name') ?? '';

        $tableArr = $table_name ? [$table_name] : [];
        $tableList = $this->model::SelectDbTableListByNames($tableArr);
        $operName = session('admin.username');
        $this->model::ImportGenTable($tableList, $operName);
        $this->success();
    }

    /**
     * @NodeAnotation(title="字段列表")
     */
    public function columnList()
    {
        $columnModel = new SystemGenTableColumn();
        $table_id = (int) $this->request->param('id') ?? '';
        $where = [['table_id', '=', $table_id]];
        $count = $columnModel
            ->where($where)
            ->count();
        $list = $columnModel
            ->where($where)
            ->select();
        $data = [
            'code'  => 0,
            'msg'   => '',
            'count' => $count,
            'data'  => $list,
        ];
        return json($data);
    }

    /**
     * @NodeAnotation(title="字段保存")
     */
    public function columnSave()
    {
        $column_id = (int) $this->request->param('id') ?? '';
        $columnModel = new SystemGenTableColumn();
        $row = $columnModel->find($column_id);
        empty($row) && $this->error('数据不存在');
        if ($this->request->isPost()) {
            $post = $this->request->post();
            $post = [$post['field'] => $post['value']];
            $rule = [];
            $this->validate($post, $rule);
            try {
                $save = $row->save($post);
            } catch (\Exception $e) {
                $this->error('保存失败:' . $e->getMessage());
            }
            $save ? $this->success('保存成功') : $this->error('保存失败');
        }
        $this->success();
    }

    /**
     * @NodeAnotation(title="test")
     */
    public function test()
    {
        $id = (int) $this->request->param('id') ?? '';
        $row = $this->model->find($id);
        empty($row) && $this->error('数据不存在');
        $controllerFilename = $row->controller_name;
        $modelFilename = $row->model_name;
        $columns = (new BuildCurdService())->setTable('test')->getTableColumns();
        dd($columns);exit;
        $this->success($controllerFilename);
    }

    /**
     * @NodeAnotation(title="代码生成")
     */
    public function gen()
    {
        $id = (int) $this->request->param('id') ?? '';
        $row = $this->model->find($id);
        empty($row) && $this->error('数据不存在');
        $controllerFilename = $row->controller_name;
        $modelFilename = $row->model_name;

        $force = 0;
        $delete = 0;

        if ($this->request->param('force')) {
            $force = 1;
        }

        if ($this->request->param('delete')) {
            $delete = 1;
        }


        $build = (new GenService())
            ->setTable($row)
            ->setForce($force);

        if ($this->request->param('runtime')) {

            $runtime_path = \think\facade\App::getRuntimePath() . 'source/build/' . date('YmdHis') . '/';
            dump($runtime_path);
            PathTools::intiDir($runtime_path . 'a.temp');

            $build->setRootDir($runtime_path);
        }

        $columns = $build->getTableColumns();

        $relations = [];

        foreach ($columns as $field => $column) {

            if (isset($column['formType']) && $column['formType'] == 'relation') {
                $define = $column['define'];

                if (!isset($define['table'])) {
                    $this->error("关联字段{$field}没有设置关联表名称");
                    return false;
                }

                $relations[] = [
                    'table'         => $define['table'],
                    'foreignKey'    => $field,
                    'primaryKey'    => $define['primaryKey'] ?? null,
                    'modelFilename' => $define['modelFilename'] ?? null,
                    'onlyFileds'    => isset($define['onlyFileds']) ? explode("|", $define['onlyFileds']) : [],
                    'relationBindSelect' => $define['relationBindSelect'] ?? null,
                ];
            }
        }

        !empty($controllerFilename) && $build = $build->setControllerFilename($controllerFilename);
        !empty($modelFilename) && $build = $build->setModelFilename($modelFilename);


        foreach ($relations as $relation) {
            $build = $build->setRelation($relation['table'], $relation['foreignKey'], $relation['primaryKey'], $relation['modelFilename'], $relation['onlyFileds'], $relation['relationBindSelect']);
        }

        $build = $build->render();
        $fileList = $build->getFileList();

        $msg = [];
        foreach ($fileList as $key => $val) {
            $msg[] = $key;
        }
        if (!$delete) {

            $result = $build->create();
            $msg[] = '自动生成CURD成功';
        } else {

            $result = $build->delete();
            $msg[] = '删除自动生成CURD文件成功';
        }
        foreach ($result as $vo) {
            $msg[] = $vo;
        }
        $msg = implode(', ', $msg);
        $this->success($msg);
    }

}